Fix OG image issues: CJK line breaking and generic title enrichment#2879
Merged
Fix OG image issues: CJK line breaking and generic title enrichment#2879
Conversation
Issue 1: CJK characters (Japanese, Chinese, Korean) are full-width (~1em) but the width estimator treated them identically to Latin characters (~0.48em). This caused titles like 'Langfuse Cloud 日本リージョンを開始しました' to be crammed onto one line instead of wrapping properly. - Add isCjkOrFullWidth() and effectiveCharCount() for accurate width estimation - Add tokenize() to split CJK text at character boundaries (not just whitespace) - Add joinTokens() to reconstruct display text with proper spacing - Update all layout functions (splitTwoLinesByWidth, splitTwoLines, greedyWordsToTitleRows, splitTitleIntoBalancedLines) to use CJK-aware splitting - Prevent CJK titles from being classified as 'short' (single-line) Issue 2: Pages with generic frontmatter titles (Overview, Get Started, etc.) now get enriched OG titles using parent folder context from the URL slug. - 'Get Started' at /docs/prompt-management/get-started becomes 'Get Started with Prompt Management' - 'Overview' at /docs becomes 'Langfuse Overview' - 'Overview' at /docs/metrics/overview becomes 'Metrics Overview' - Pages with explicit seoTitle are unchanged Co-authored-by: felixkrrr <felixkrrr@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Generic frontmatter titles like 'Get Started' and 'Overview' now render enriched in both the OG image AND the page <title> tag: - 'Get Started - Langfuse' → 'Get Started with Prompt Management - Langfuse' - 'Overview - Langfuse' → 'Langfuse Overview - Langfuse' Pages with explicit seoTitle in frontmatter are unaffected. Co-authored-by: felixkrrr <felixkrrr@users.noreply.github.com>
|
@claude review |
Contributor
Author
The effective char count threshold was 105/0.48 ≈ 219, which could never fire because the t.length > 105 guard above catches all strings that long. A 40-char CJK title (visually as wide as ~83 Latin chars) was never routed to fitTitleLayoutLong. Using 105 directly means 'this title has the visual weight of a 105-char Latin string.' Addresses PR review comment from greptile. Co-authored-by: felixkrrr <felixkrrr@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes LFE-9532 — two OG image issues.
Issue 1: CJK line break broken
Before: Japanese titles like "Langfuse Cloud 日本リージョンを開始しました" were crammed onto a single line that overflowed, because the width estimator treated CJK characters (~1em wide) identically to Latin characters (~0.48em).
After: The title correctly wraps into two lines.
Changes in
app/api/og/route.tsx:isCjkOrFullWidth()to detect CJK/full-width Unicode codepoints (Hiragana, Katakana, CJK ideographs, Hangul, etc.)effectiveCharCount()that weighs CJK characters at1.0 / emunits instead of 1, makingapproxLineWidthPx()accurate for mixed-script texttokenize()to split CJK text at individual character boundaries (since CJK text often has no whitespace between words)joinTokens()to reconstruct display text with proper spacing between token typessplitTwoLinesByWidth,splitTwoLines,greedyWordsToTitleRows, andsplitTitleIntoBalancedLinesto use CJK-aware tokenizationJapanese OG image - properly line-wrapped
Issue 2: Generic OG titles not descriptive enough
Before: Pages like
/docs/prompt-management/get-startedshowed just "Get Started" in the OG image, and/docsshowed just "Overview" — not meaningful in social shares.After: Generic titles are automatically enriched with parent folder context:
/docs) → "Langfuse Overview"/docs/metrics/overview) → "Metrics Overview"Pages with explicit
seoTitlefrontmatter are not affected.Changes in
lib/mdx-page.ts:GENERIC_TITLESset of titles that need enrichmentslugSegmentToTitle()to convert slug segments to title case (with known abbreviation overrides for API, SDK, FAQ, LLM, MCP, UI)enrichOgTitle()that prepends parent context for generic titlesbuildSectionMetadata()now uses enriched titles for OG images only (the page<title>tag is unchanged)Get Started OG image - enriched title
Langfuse Overview OG image
To show artifacts inline, enable in settings.
Linear Issue: LFE-9532
Disclaimer: Experimental PR review
Greptile Summary
This PR fixes two OG image issues: CJK text (Japanese/Korean/Chinese) now wraps correctly via a new
isCjkOrFullWidthdetector,effectiveCharCountwidth estimator, andtokenize/joinTokenshelpers; and generic page titles like "Overview" or "Get Started" are automatically enriched with parent-slug context viaenrichOgTitleinlib/mdx-page.ts, leaving the page<title>tag unchanged.Confidence Score: 5/5
Safe to merge — no logic bugs found; only minor style inconsistencies flagged.
All P2 findings. The raw-length check in splitTwoLines is harmless because the pixel-budget check in tryTwoLineLayout catches any oversized candidates, and the primary splitTwoLinesByWidth path handles CJK correctly. The enrichOgTitle changes are isolated to OG metadata only.
No files require special attention.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[fitTitleLayout] -->|isLongTitle?| B[fitTitleLayoutLong] A -->|isShortTitle?| C[fitTitleLayoutSingleLine] A --> D[splitTwoLinesByWidth\nCJK-aware pixel budget] A --> E[splitTwoLines\nchar budget fallback] A --> F[wrapWords\nchar-cap fallback] D --> G{tryTwoLineLayout\ntitleLinesFitRenderConstraints} E --> G F --> G subgraph CJK helpers H[hasCjk] I[tokenize\nper-char for CJK] J[joinTokens\nno space CJK-CJK] K[effectiveCharCount\n1/em units for CJK] L[approxLineWidthPx\nuses effectiveCharCount] end D --> I E --> I I --> J L --> K subgraph OG title enrichment M[buildSectionMetadata] --> N{pageData.seoTitle?} N -->|yes| O[use seoTitle as-is] N -->|no| P[enrichOgTitle] P --> Q{GENERIC_TITLES match?} Q -->|no| R[return title unchanged] Q -->|yes| S{slug.length} S -->|>=2| T[slugSegmentToTitle slug at -2] S -->|0| U[Langfuse prefix] S -->|1| V[sectionTitle prefix] endPrompt To Fix All With AI
Reviews (2): Last reviewed commit: "Fix isLongTitle CJK threshold: use 105 n..." | Re-trigger Greptile